﻿using System;
using System.Collections.Generic;

public class FieldInfo
{
    private BidirectionDictionary<BaseGrid, BaseChess> gridChessBiDict = new BidirectionDictionary<BaseGrid, BaseChess>();
    private CampInfo[] campInfos;
    public FieldInfo(List<int> campTeamList, List<(Pos, Type, int)> chessTypeCampList, BaseChessBoard chessBoard)
    {
        int campCount = campTeamList.Count;
        campInfos = new CampInfo[campCount];
        List<List<BaseChess>> chessListList = new List<List<BaseChess>>();
        for (int i = 0; i < campCount; i++)
        {
            chessListList.Add(new List<BaseChess>());
        }
        for (int i = 0; i < chessTypeCampList.Count; i++)
        {
            (Pos, Type, int) infos = chessTypeCampList[i];
            BaseChess chess = (BaseChess)Activator.CreateInstance(infos.Item2, new object[] { infos.Item3, campTeamList[infos.Item3] });
            chessListList[chess.GetCamp()].Add(chess);
        }
        for (int i = 0; i < campCount; i++)
        {
            campInfos[i] = new CampInfo(i, campTeamList[i], chessListList[i], chessBoard);
        }
    }
    public void Init(List<(Pos, Type, int)> chessTypeCampList, BaseChessBoard chessBoard)
    {
        int campCount = campInfos.Length;
        Dictionary<Type, List<BaseChess>[]> dict = new Dictionary<Type, List<BaseChess>[]>();
        for (int i = 0; i < campCount; i++)
        {
            HashSet<BaseChess> chessSet = campInfos[i].DirectGetOfflineChessSet();
            foreach (BaseChess chess in chessSet)
            {
                Type type = chess.GetType();
                int camp = chess.GetCamp();
                if (!dict.ContainsKey(type))
                {
                    dict.Add(type, new List<BaseChess>[campCount]);
                    for (int j = 0; j < campCount; j++)
                    {
                        dict[type][j] = new List<BaseChess>();
                    }
                }
                dict[type][camp].Add(chess);
            }
        }
        List<BaseChess>[] onChessListArray = new List<BaseChess>[campCount];
        for (int i = 0; i < campCount; i++)
        {
            onChessListArray[i] = new List<BaseChess>();
        }
        for (int i = 0; i < chessTypeCampList.Count; i++)
        {
            (Pos, Type, int) infos = chessTypeCampList[i];
            List<BaseChess> tempList = dict[infos.Item2][infos.Item3];
            BaseChess chess = tempList[tempList.Count - 1];
            tempList.RemoveAt(tempList.Count - 1);
            gridChessBiDict.Add(chessBoard.GetGridByPos(infos.Item1), chess);
            onChessListArray[infos.Item3].Add(chess);
        }
        for (int i = 0; i < campCount; i++)
        {
            campInfos[i].Init(onChessListArray[i], chessBoard);
        }
    }
    public BaseChess GetChessByGrid(BaseGrid grid)
    {
        if (gridChessBiDict.ContainsKey(grid))
        {
            return gridChessBiDict.GetValueByKey(grid);
        }
        else
        {
            return null;
        }
    }
    public BaseGrid GetGridByChess(BaseChess chess)
    {
        if (gridChessBiDict.ContainsValue(chess))
        {
            return gridChessBiDict.GetKeyByValue(chess);
        }
        else
        {
            return null;
        }
    }
    //调用频繁，直接返回集合
    public HashSet<BaseChess> DirectGetOnlineChessSetByCamp(int camp)
    {
        return campInfos[camp].DirectGetOnlineChessSet();
    }
    public HashSet<BaseChess> DirectGetOfflineChessSetByCamp(int camp)
    {
        return campInfos[camp].DirectGetOfflineChessSet();
    }
    public List<BaseChess> GetAllChessList()
    {
        List<BaseChess> chessList = new List<BaseChess>();
        for (int i = 0; i < campInfos.Length; i++)
        {
            chessList.AddRange(campInfos[i].GetAllChessList());
        }
        return chessList;
    }
    public int GetCampCount()
    {
        return campInfos.Length;
    }
    //己方队伍和其他所有队伍分数之差
    public Score GetTeamScoreDifferenceByCamp(int camp)
    {
        int team = campInfos[camp].GetTeam();
        Score result = new Score(0, 0);
        for (int i = 0; i < campInfos.Length; i++)
        {
            Score tempScore = campInfos[i].GetCampScore(); ;
            if (campInfos[i].GetTeam() == team)
            {
                result = result.AddResult(tempScore);
            }
            else
            {
                result = result.SubResult(tempScore);
            }
        }
        return result;
    }
    //己方胜利
    public bool IsAllOtherTeamFailByCamp(int camp)
    {
        int team = campInfos[camp].GetTeam();
        bool result = true;
        for (int i = 0; i < campInfos.Length; i++)
        {
            if (campInfos[i].GetTeam() == team && campInfos[i].GetCampScore().infCount > 0)
            {
                result = false;
            }
        }
        return result;
    }
    public Score GetCampScore(int camp)
    {
        return campInfos[camp].GetCampScore();
    }
    public int GetTeamByCamp(int camp)
    {
        return campInfos[camp].GetTeam();
    }
    public void ChessOn(BaseChess chess, Pos pos, BaseChessBoard chessBoard)
    {
        //注意先后顺序
        gridChessBiDict.Add(chessBoard.GetGridByPos(pos), chess);
        campInfos[chess.GetCamp()].ChessOn(chess, chessBoard);
    }
    public void ChessOff(BaseChess chess, BaseChessBoard chessBoard)
    {
        //注意先后顺序
        campInfos[chess.GetCamp()].ChessOff(chess, chessBoard);
        gridChessBiDict.RemoveByValue(chess);
    }
    public void ChessMove(BaseChess chess, Pos pos, BaseChessBoard chessBoard)
    {
        ChessOff(chess, chessBoard);
        ChessOn(chess, pos, chessBoard);
    }
}